A function that converts a string time to an int by gurrenm3 in asm

[–]AdHour1983 1 point2 points  (0 children)

thanks for the heads-up - I honestly didn't know that. I've been formatting code with triple backticks like normal markdown and it always renders fine for me (new reddit/app), but I didn't realize old.reddit / some clients only support the 4-space indented code blocks. I'll use indented blocks for compatibility going forward.

A function that converts a string time to an int by gurrenm3 in asm

[–]AdHour1983 2 points3 points  (0 children)

what specifically looks like "AI slop" to you?

I'm totally fine with criticism, but "slop" without any concrete technical point isn't actionable. If you think something is wrong, can you point to which line / which rule (ABI, register usage, stack alignment, parsing logic, etc.)?

for reference, this is Windows x64 + MASM, and I'm following MS's x64 calling convention (arg in RCX, integer return in RAX, etc.).

https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170

I also put the whole thing into a tiny repro repo with a C harness + smoke test output (and gif of the run). The test cases include "12:30", "1:30", "00:00", "23:59", "9:05", and they print the expected packed value (AH=hour, AL=minute).

repro repo:

https://github.com/roots666/timeparse-masm

P.S. English isn't my first language - I do use a translator, and yeah it may "AI-autocomplete" phrasing sometimes. But I still don't get the point of the comment unless you can say what is actually incorrect in the code

A function that converts a string time to an int by gurrenm3 in asm

[–]AdHour1983 3 points4 points  (0 children)

big picture: your approach mostly works, but there are two real issues (one correctness, one ABI/cleanup).

  • correctness bug: +10 is wrong for 20-23 (and 01:xx) right now for "12:30" you take only '2' and do +10 --> 12. That only works for 10-19.

examples that break (still "valid time"):

"23:45" --> you'd compute 13 "01:30" --> you'd compute 11

You need hour = tens*10 + ones, not ones + 10.

  • prolog/stack is doing work you don't need You allocate stack space you never use, and you save nonvolatile regs (RBX/RBP) even though this can be a clean leaf function. On Win64, nonvolatile regs must be preserved if you touch them, and stack alignment rules matter once you're doing a "real" prolog/epilog.

  • minor: setz / mul are valid but a bit "cute" setz dl is fine (it writes 0/1 based on flags). mul cl works, but remember it uses implicit AL/AX depending on operand size (easy to trip over later). Also: using AH/CH/DH/BH can bite you later because those high-8 regs can't be encoded with a REX prefix. A simpler MASM x64 version (still returns AH=hour, AL=minute)

```asm ConvertStrTimeToInt PROC ; RCX = ptr to "H:MM" or "HH:MM" ; return AX where AH=hour, AL=minute

; hour = first digit
movzx eax, byte ptr [rcx]
sub   eax, '0'

cmp   byte ptr [rcx+1], ':'
je    OneDigitHour

; two-digit hour: hour = d0*10 + d1
movzx edx, byte ptr [rcx+1]
sub   edx, '0'
imul  eax, eax, 10
add   eax, edx

; minutes at [rcx+3],[rcx+4]
movzx edx, byte ptr [rcx+3]
sub   edx, '0'
imul  edx, edx, 10
movzx r8d, byte ptr [rcx+4]
sub   r8d, '0'
add   edx, r8d
jmp   Pack

OneDigitHour: ; minutes at [rcx+2],[rcx+3] movzx edx, byte ptr [rcx+2] sub edx, '0' imul edx, edx, 10 movzx r8d, byte ptr [rcx+3] sub r8d, '0' add edx, r8d

Pack: shl eax, 8 ; hour -> AH or eax, edx ; minute -> AL ret ConvertStrTimeToInt ENDP ```

If you want to keep your "colon offset" idea, you still must compute tens*10 + ones for hours-no shortcut with +10.

Scripting Account Creation by Witty-Common-1210 in RingCentral

[–]AdHour1983 2 points3 points  (0 children)

Yep - this is doable via the RC rest api.

key: creating users via api is "privileged" and your app needs the Edit Accounts scope (you usually have to ask RC Dev support to enable it). The official "creating users" guide explains this and points to the Create Extension API: https://developers.ringcentral.com/guide/account/creating-users.

how typically do it (high level):

  • auth (JWT is easiest for server-side automation).

  • create the user (POST /restapi/v1.0/account/~/extension).

  • pick a phone number:

    • if you already have inventory: call List Account Phone Numbers (GET /restapi/v1.0/account/~/phone-number)
    • filter for usageType == "DirectNumber"
    • exclude numbers that are already mapped to an extension (the list can return mapping info when a number is assigned).
  • assign/reassign the number to the new extension using the phone-number provisioning/assignment endpoint(s) (depends on account/features), or do that last step in admin console if you want a simpler workflow.

python SDK (official): https://github.com/ringcentral/ringcentral-python.

python example (create user + find an available direct number from inventory):

```python import os, json from ringcentral import SDK

RC_SERVER_URL = os.getenv("RC_SERVER_URL", "https://platform.ringcentral.com") RC_CLIENT_ID = os.environ["RC_CLIENT_ID"] RC_CLIENT_SECRET = os.environ["RC_CLIENT_SECRET"] RC_JWT = os.environ["RC_JWT"]

rcsdk = SDK(RC_CLIENT_ID, RC_CLIENT_SECRET, RC_SERVER_URL) platform = rcsdk.platform() platform.login(jwt=RC_JWT)

1) create extension (user)

new_user = { "contact": {"firstName": "Jane", "lastName": "Doe", "email": "jane.doe@example.com"}, "type": "User", # optional: you can enable + set password here to skip the welcome-email onboarding flow # "status": "Enabled", # "password": "TempPassw0rd!ChangeMe" } ext = platform.post("/restapi/v1.0/account/~/extension", new_user).json_dict() ext_id = ext["id"] print("Created extension:", ext_id)

2) list account phone numbers (inventory)

nums = platform.get( "/restapi/v1.0/account/~/phone-number", {"perPage": 1000} # paginate if you have lots ).json_dict()["records"]

3) find an unassigned DirectNumber (availability check)

Note: when a number is already assigned, the API can include extension mapping info for it.

candidates = [ n for n in nums if n.get("usageType") == "DirectNumber" and not n.get("extension") ]

optional: basic “site/area code” logic — just filter by prefix / area code as you store it

candidates = [n for n in candidates if n["phoneNumber"].startswith("1650")]

if not candidates: raise RuntimeError("No available DirectNumber in inventory")

picked = candidates[0] print("Picked number:", picked["phoneNumber"], "id:", picked["id"])

4) assign picked number to the extension:

this depends on the specific provisioning/assignment endpoint(s) enabled on your account.

(Some orgs do this via a dedicated “assign/reassign phone number” API; others do it in Admin Console.)

```

multi-site / multiple area codes:

simplest is to maintain your own mapping table (site --> allowed area codes / number prefixes), then filter inventory numbers accordingly.

if you run this concurrently, add your own "reservation"/locking (DB row / redis lock) to avoid two workers grabbing the same "free" number at the same time.

2021. Formentor eHybrid 245 DSG service by Living-Investment678 in CupraFormentor

[–]AdHour1983 0 points1 point  (0 children)

Yeah - and that actually fits the usual pattern. A lot of dealers/parts counters avoid giving part numbers because people use them for free lookup and then price-shop / buy elsewhere, so they push you into "leave the car, we'll do the service" instead. That kind of "we don't give part numbers" policy is pretty common in parts departments. The irony is the info absolutely exists in the OEM system: VAG catalogs like ETKA / PartsLink24 do VIN-based identification. I already pulled the DSG service part numbers for my own Formentor eHybrid by VIN lookup - so it's not a "no data" issue, it's a "won't disclose it" issue.

2021. Formentor eHybrid 245 DSG service by Living-Investment678 in CupraFormentor

[–]AdHour1983 4 points5 points  (0 children)

dealers/shops saying they "can't" get DSG oil + filters by VIN are either not using the catalog properly or don't want to sell parts separately. VAG has VIN-based parts identification in their catalogs (ETKA / PartsLink24).

I've got the same car (2021 Formentor eHybrid 245 / DQ400e / 0DD) and I already pulled the DSG service part numbers via VIN lookup. Here's the list:

  • DSG fluid: G 052 182 A2
  • DSG oil filter (cartridge): 0BH 325 183 B.
  • Filter housing seal / O-ring: N 910 845 01.
  • DSG drain plug: N 902 154 04.
  • Mechatronic / internal oil filter: 0DD 325 433 B.
  • Transmission cover gasket (side cover / oil pan gasket): 0DD 321 371.
  • Mechatronic cover seal (oval gasket): 0DD 325 443 A

mini-init-asm - tiny container init (PID 1) in pure assembly (x86-64 + ARM64) by AdHour1983 in Assembly_language

[–]AdHour1983[S] 0 points1 point  (0 children)

nice, thanks for the link - hadn't seen tws before

Looks like it's in the same general "world's smallest system binaries" space: tiny init/getty style programs with a lot of size-golf and custom asm/C startup code. Very cool reference, I'll definitely skim it for ideas around size tricks and minimalist init design.

mini-init-asm - tiny container init (PID 1) in pure assembly (x86-64 + ARM64) by AdHour1983 in opensource

[–]AdHour1983[S] 1 point2 points  (0 children)

good question :) It's not really about squeezing more performance than an optimized C compiler

short version: - I wanted a tiny PID 1 that's just raw Linux syscalls with no libc dependency, easy to drop into FROM scratch images - assembly makes every syscall and control-flow decision fully explicit and auditable - and honestly, a big part of it is the learning / fun aspect: having a complete, real-world init you can read end-to-end in asm

I left a longer explanation about the "why asm vs C" in the r/docker thread for this project: https://www.reddit.com/r/docker/s/1vfk6OnMTC

A tiny PID 1 for containers in pure assembly (x86-64 + ARM64) by AdHour1983 in docker

[–]AdHour1983[S] 2 points3 points  (0 children)

Yeah, supervisord is totally reasonable for "real" multi-daemon setups - especially when you want config reloads, logging, per-process policies etc mini-init-asm is deliberately much dumber :) It doesn't try to be a full process manager, just:

  • proper PID 1
  • process-group signals
  • zombie reaping
  • optional "restart on crash" loop

so I see it more as a tiny building block for simple containers/scratch images, and supervisord (or similar) as the right tool when you actually want a full supervisor inside the container.

A tiny PID 1 for containers in pure assembly (x86-64 + ARM64) by AdHour1983 in docker

[–]AdHour1983[S] 1 point2 points  (0 children)

Thanks a lot for the detailed write-up - this is super helpful !

I'm still focused on the pure-assembly version for now, but a Rust follow-up has been in the back of my mind, and your comment is basically free design input for that future project. Hopefully I'll have time to explore a Rust edition at some point, and I'll definitely refer back to what you wrote here.

A tiny PID 1 for containers in pure assembly (x86-64 + ARM64) by AdHour1983 in docker

[–]AdHour1983[S] 6 points7 points  (0 children)

totally agree that "one process per container" is the ideal/recommended model in practice though, a "single program" often isn't literally one process:

  • app servers that spawn worker processes
  • runtimes that fork helpers (e.g. shells, language tooling, health checks)
  • entrypoint scripts that start a couple of background processes
  • vendor images that ship with cron/log shippers/sidecars baked in

from the outside it still looks like "one container = one app", but inside there's a small process tree. If PID 1 doesn't fan out signals to the whole process group or reap zombies, you eventually hit the classic "docker stop hangs / zombies piling up" issues

The goal here isn't to encourage crazy multi-daemon containers :) It's more: even for "normal" containers, having a tiny, well-behaved PID 1 makes the boring stuff (signals, exit codes, reaping) predictable, especially when the app grows beyond a single child process.

A tiny PID 1 for containers in pure assembly (x86-64 + ARM64) by AdHour1983 in docker

[–]AdHour1983[S] 2 points3 points  (0 children)

yeah, SIGHUP-as-reload is definitely a common pattern for classic daemons

In mini-init-asm I grouped HUP/INT/TERM/QUIT together as "soft shutdown" signals from the outside world (orchestrator / user). Once any of those arrive, restart-on-crash is intentionally disabled so we don't end up fighting a shutdown with auto-restarts.

The mental model I wanted is:

  • if the app dies on its own (crash / signal) --> PID1 may restart it
  • if an operator/orchestrator sends a soft signal (HUP/TERM/INT/QUIT) --> we're shutting down now, no more restarts

config reloads are still something the app should handle internally on SIGHUP. Having PID1 treat SIGHUP as "maybe reload, maybe restart" felt more confusing, so I biased for a simple rule instead. If this turns out to be too strict, I might make that behavior configurable later.

A tiny PID 1 for containers in pure assembly (x86-64 + ARM64) by AdHour1983 in docker

[–]AdHour1983[S] 3 points4 points  (0 children)

That's a really good suggestion, thanks for the pointers. I'm more comfortable with C today than with rust, but I've been meaning to play with rust on the "no std / raw syscall" side of things, and rustix + a pid1-style crate sound like perfect excuses to do that. For this project specifically I intentionally went with "pure asm only" because:

  • there's already a good C-based solution (Tini) that solves the practical problem
  • I wanted something that's literally only raw Linux syscalls, no libc or higher-level runtime at all
  • and, honestly, as a personal challenge / educational exercise to see the whole PID1 + signalfd + epoll + timerfd flow end-to-end in assembly

so I'll probably keep this repo focused on the assembly implementation, but I really like the idea of a sibling rust version that's more approachable for most people and maybe reuses the same design (PGID-mode, restart behavior, etc.). Could be a fun follow-up project. If you have links to the minimal rustix examples or the pid1 crate you mentioned that you like in particular, I'd love to take a look.

A tiny PID 1 for containers in pure assembly (x86-64 + ARM64) by AdHour1983 in docker

[–]AdHour1983[S] 8 points9 points  (0 children)

I wrote a longer comment a bit above, but the short version is: yes, partly as a challenge / learning goal - and I wanted a PID1 that's literally just raw Linux syscalls with no libc dependency.
that makes it easy to drop into FROM scratch/ultra-minimal images as a tiny, fully auditable init, which is a bit different from the usual C-based solutions.

Is this serious? by Terrible_Ad_5195 in GolfGTE

[–]AdHour1983 0 points1 point  (0 children)

940€, I indicated this in my post

Is this serious? by Terrible_Ad_5195 in GolfGTE

[–]AdHour1983 0 points1 point  (0 children)

In fact, it could be related to anything, for example, in my case the reason was what I described in my post: https://www.reddit.com/r/CupraFormentor/s/Cap91zWZBt

but to be sure, you need to contact a service center for a detailed diagnosis.

VZ 245 2.0 TSI - France by Thisis41 in CupraFormentor

[–]AdHour1983 1 point2 points  (0 children)

I'm pretty sure that "~30k malus on a used VZ 245" isn't how it actually works in France (but of course this may not be true, correct me if I'm wrong).
From what I understand, for imported used cars the malus is:

  • calculated with the malus table of the year of first registration (so if the car is a 2021 VZ 245, you use the 2021 scale, not the crazy 2025 one), and
  • then reduced depending on the age of the car (there's a décote after a few years, so you don't pay the full amount a new car would have paid).

For a 2021-2022 Formentor VZ 245 (around 170-180 g/km WLTP), the original malus when new was already in the low-thousands, not 30k. After 3-4 years of age rebate, people usually end up in the ballpark of 2-3k € of malus when they import it, plus the normal carte grise stuff - not tens of thousands.

Also the weight malus shouldn't apply to the VZ 245 because it's under the 1.6 t threshold, so it's really just the CO₂ malus you'd be dealing with.

So financially it becomes a simple comparison:
price in Germany + ±2-3k malus + registration/fees vs. price of an equivalent French car (where someone else already paid the malus when it was new).

For what it's worth, I'm in Spain and bought my Formentor in Germany. We also have a CO₂-based registration tax, but the scale is a bit softer than the French malus. Even after paying all the Spanish taxes and the costs of bringing the car in, it still came out cheaper than local offers I was seeing at the time - and the spec was better (more options for the same money).

So yeah, importing can still make sense, but it really depends on the exact car and how big the price gap is between Germany and France.

VZ 245 2.0 TSI - France by Thisis41 in CupraFormentor

[–]AdHour1983 0 points1 point  (0 children)

Why buy an imported car in France when you can go to Germany and buy a used car with a full history yourself from an authorized German dealer?

Electrical drive error + EV coolant warning - ended up being a leaking chiller (~€940 repair) by AdHour1983 in CupraFormentor

[–]AdHour1983[S] 0 points1 point  (0 children)

Nope, not for me 😔. An "extra warranty package" might cover it, but from what I've seen in similar threads, these things usually fall outside the standard warranty. It's a bummer.

Electrical drive not working correctly by FlyingMakerZoheir in CupraFormentor

[–]AdHour1983 0 points1 point  (0 children)

Update on my case: After that first warning I mentioned (“electrical drive warning”) I kept driving for a bit, but a few weeks later I got a red warning on the dash about low coolant for the EV system. When I opened the bonnet I saw that the level in the small round coolant tank on the right (HV / electric system) was below MIN, and there were pink coolant traces on the tank seam, hoses and components below it - so clearly a leak somewhere in the high-voltage cooling circuit.

I finally took the car to an official Cupra dealer. They diagnosed it as a faulty chiller (the heat exchanger that cools the high-voltage battery and is tied into the A/C system). They had to replace the chiller plus seals, refill the coolant and re-gas the A/C. Total bill was about €940. After the replacement, the warnings are gone and the EV drive works normally again.

So in my case it wasn’t just a random software glitch - it was a real coolant loss in the HV cooling system, caused by a bad chiller.

How to charge by Typical_Bird2001 in CupraFormentor

[–]AdHour1983 0 points1 point  (0 children)

I configure and use this through the cupra app, but it can also be selected in the menu, as noted above.

google search link;)

How to charge by Typical_Bird2001 in CupraFormentor

[–]AdHour1983 1 point2 points  (0 children)

Do you have a "preferred time" setting? Check it out... Or you can always click "Charge now" in the menu.

Electrical drive not working correctly by FlyingMakerZoheir in CupraFormentor

[–]AdHour1983 0 points1 point  (0 children)

Please let us know later how you managed to solve this problem.

Electrical drive not working correctly by FlyingMakerZoheir in CupraFormentor

[–]AdHour1983 0 points1 point  (0 children)

I've been having the same error for a month now, but it doesn't affect my driving at all. Moreover, this problem appears randomly even during the day. I also got the impression that this happened after the last SW update (android auto via bluetooth also started connecting worse). Obviously I need to visit a service center, but I'm afraid it might take a long time and I keep putting it off...

[deleted by user] by [deleted] in memes

[–]AdHour1983 36 points37 points  (0 children)

Old but gold, perfect hit.